/*
 * @Description: 工具类
 * @Version: V1.0.0
 * @Author: 黄鑫
 * @Date: 2024-08-20 10:54:11
 * @LastEditors: 黄鑫
 * @LastEditTime: 2025-08-19
 * @FilePath: HXUtils.dart
 * @Props: 
 * @Remarks: 
 */
import 'dart:convert';
import 'package:date_format/date_format.dart';
import 'package:flutter/material.dart';
import 'package:flutter_cupertino_datetime_picker2/flutter_cupertino_datetime_picker2.dart';
import 'package:encrypt/encrypt.dart' as encrypt;
import 'package:hx_base/resource/Assets.dart';
import 'package:pointycastle/asymmetric/api.dart';

class HXUtils {
  ///隐藏键盘
  static hideKeyboard() {
    FocusManager.instance.primaryFocus?.unfocus();
  }

  // 格式化打印 JSON 数据
  static String prettyPrintJson(String jsonStr) {
    var decodedJson = jsonDecode(jsonStr); // 解析 JSON 字符串
    var encoder = JsonEncoder.withIndent('  '); // 使用 2 个空格缩进格式化
    return encoder.convert(decodedJson);
  }

  // 文件图标名
  static Widget getImageIcon(String type, {double size = 20}) {
    switch (type) {
      case ".doc":
      case ".docx":
        return Image.asset(Assets.imagesDocIcon,
            package: "hx_base", width: size, height: size);
      case ".pdf":
        return Image.asset(Assets.imagesPdfIcon,
            package: "hx_base", width: size, height: size);
      case ".xlsx":
        return Image.asset(Assets.imagesExcelIcon,
            package: "hx_base", width: size, height: size);
      case ".txt":
        return Image.asset(Assets.imagesTxtIcon,
            package: "hx_base", width: size, height: size);
      default:
        return Icon(Icons.description, size: size);
    }
  }

  // 时间滚轮筛选
  static showDatePicker(BuildContext context, int timeType,
      DateTime currentTime, Function(DateTime selectTime) selectTime) {
    // 日期滚轮选择
    String dateFormat = 'yyyy年 MM月 dd日';
    if (timeType == 2) {
      dateFormat = 'yyyy年 MM月 dd日';
    }
    if (timeType == 3) {
      dateFormat = 'yyyy年 MM月';
    }
    if (timeType == 4) {
      dateFormat = 'yyyy年';
    }
    DatePicker.showDatePicker(
      context,
      locale: DateTimePickerLocale.zh_cn,
      dateFormat: dateFormat,
      initialDateTime: currentTime,
      maxDateTime: DateTime.now().add(Duration(days: 2)),
      minDateTime: DateTime(2024, 1, 1),
      onConfirm: (dateTime, selectedIndex) {
        selectTime(dateTime);
      },
    );
  }

  // RSA加密
  static String stirngWithRSA(String str, String priKey) {
    // 解析rsa公钥
    final publicKey = encrypt.RSAKeyParser().parse(priKey);
    // 创建rsa加密器
    final encrypter =
        encrypt.Encrypter(encrypt.RSA(publicKey: publicKey as RSAPublicKey));
    return encrypter.encrypt(str).base64;
  }

  // AES解密
  static Map decryptAES(String encryptedString, String aesKey, String priKey) {
    // AES 需要的密钥和 IV
    final key = encrypt.Key.fromUtf8(aesKey);
    final ivstr = priKey.replaceAll(RegExp(r'[\r\n]+'), "").substring(26, 42);
    final iv = encrypt.IV.fromUtf8(ivstr);
    final encrypter = encrypt.Encrypter(
        encrypt.AES(key, mode: encrypt.AESMode.cbc)); // 使用 CBC 模式
    final decrypted = encrypter.decrypt64(encryptedString, iv: iv);
    return jsonDecode(decrypted);
  }

  // 日期格式化
  static String getTimeFormat(int timeType, DateTime currentTime) {
    switch (timeType) {
      // 天
      case 2:
        return formatDate(currentTime, [yyyy, "-", mm, "-", dd]);
      // 月
      case 3:
        return formatDate(currentTime, [
          yyyy,
          "-",
          mm,
        ]);
      // 年
      case 4:
        return formatDate(currentTime, [yyyy]);
      // 周
      case 5:
        int offset = currentTime.weekday - DateTime.monday;
        DateTime weekDay = currentTime.subtract(Duration(days: offset));
        return formatDate(weekDay, [yyyy, "-", mm, "-", dd]);
      default:
        return "";
    }
  }

  // 去掉HTML标签
  static String removeHtmlTagsAndContent(String htmlString) {
    final regex =
        RegExp(r'<a [^>]*>.*?</a>', multiLine: true, caseSensitive: false);
    return htmlString.replaceAll(regex, '');
  }

  // 判断是否有HTML标签
  static bool containsHtmlTags(String input) {
    RegExp regex = RegExp(r'<[^>]+>', multiLine: true, caseSensitive: false);
    return regex.hasMatch(input);
  }

  // 提取HTML标签的href内容
  static List<String> extractHrefValues(String input) {
    RegExp regex = RegExp('<a [^>]*href=[\'"]([^\'"]+)[\'"][^>]*>',
        multiLine: true, caseSensitive: false);
    Iterable<Match> matches = regex.allMatches(input);
    return matches.map((match) => match.group(1)!).toList();
  }

  // 提取HTML标签中的内容
  static String extractInnerTextWithRegex(String htmlString) {
    final regex = RegExp(r'>([^<>]+)<');
    final match = regex.firstMatch(htmlString);
    return match != null ? match.group(1)?.trim() ?? '' : '';
  }

  // 颜色格式化
  static Color? hexToColor(String? hexString) {
    if (hexString == null || hexString.trim().isEmpty) {
      return null;
    }
    hexString = hexString.replaceAll('#', '').toUpperCase();
    if (hexString.length == 6) {
      // RGB → ARGB，默认不透明
      hexString = 'FF$hexString';
    } else if (hexString.length == 8) {
      // RGBA → ARGB（A在最后，转到前面）
      hexString = hexString.substring(6, 8) + hexString.substring(0, 6);
    } else {
      return null; // 格式不正确
    }

    try {
      return Color(int.parse(hexString, radix: 16));
    } catch (e) {
      return null;
    }
  }

  // 时间格式化 传入时间戳，返回格式化字符串
  static String hxFormatDate(int? date, List<String> formats,
      {String nullStr = "-"}) {
    if (date == null) {
      return nullStr;
    }
    return formatDate(DateTime.fromMillisecondsSinceEpoch(date), formats);
  }

  // 时间差返回X天X小时X分 传入都是毫秒
  static String formatDuration({int? startTime, int? endTime, int? second}) {
    int seconds = 0;

    if (second != null) {
      seconds = second;
    } else if (startTime != null && endTime != null) {
      if (startTime <= 0 || endTime <= 0 || endTime < startTime) {
        return "-";
      }
      seconds = endTime - startTime;
    } else {
      // 参数不合法
      return "-";
    }
    if (seconds <= 0) {
      return "-";
    }
    seconds = seconds ~/ 1000;
    int days = seconds ~/ (24 * 3600);
    int hours = (seconds % (24 * 3600)) ~/ 3600;
    int minutes = (seconds % 3600) ~/ 60;

    String result = '';
    if (days > 0) result += '$days天';
    if (hours > 0) result += '$hours小时';
    if (minutes > 0) result += '$minutes分钟';
    return result.isNotEmpty ? result : '0分钟'; // 确保返回值不会为空
  }

  // 解析URL
  static UrlInfoModel? parseUrlInfo(String url) {
    try {
      final uri = Uri.parse(url);
      UrlInfoModel infoModel = UrlInfoModel();
      infoModel.scheme = uri.scheme; //协议 https
      infoModel.host = uri.host; // 主机名，如 example.com
      infoModel.port = uri.port; // 端口号，如 8080（默认 https 为 443）
      infoModel.path = uri.path; // 路径，如 /user/profile
      infoModel.query = uri.query; // 查询字符串，如 id=1&tab=info
      infoModel.queryParameters =
          uri.queryParameters; // 查询参数 Map，如 {id: 1, tab: info}
      return infoModel;
    } catch (e) {
      return null;
    }
  }

  // 处理小数数据，最多保留两位小数，去掉多余的0
  static String handleFormatDecimalValue(var value, {String hint = ""}) {
    if (value == null) {
      return hint;
    }
    double? doubleValue = double.tryParse(value.toString());
    if (doubleValue == null) {
      return value;
    }
    String valueStr = doubleValue.toStringAsFixed(2);
    return valueStr.replaceFirst(RegExp(r'\.?0+$'), '');
  }
}

class UrlInfoModel {
  String? scheme;
  String? host;
  int? port;
  String? path;
  String? query;
  Map? queryParameters;

  UrlInfoModel(
      {this.scheme,
      this.host,
      this.port,
      this.path,
      this.query,
      this.queryParameters});

  UrlInfoModel.fromJson(Map<String, dynamic> json) {
    scheme = json['scheme'];
    host = json['host'];
    port = json['port'];
    path = json['path'];
    query = json['query'];
    queryParameters = json['queryParameters'];
  }

  Map<String, dynamic> toJson() {
    final Map<String, dynamic> data = <String, dynamic>{};
    data['scheme'] = scheme;
    data['host'] = host;
    data['port'] = port;
    data['path'] = path;
    data['query'] = query;
    if (queryParameters != null) {
      data['queryParameters'] = queryParameters;
    }
    return data;
  }
}
